/*********************************************************************************
Organization 					: 				Georgia Institute of Technology
  
Institute 						:				Cognitive Computing Group(CCL)
 
Authors							: 				Santiago Ontanon, Kinshuk Mishra
 												Neha Sugandh 
 												
Class							:				WinWargusGoal
 
Function						: 				Provides a class for holding the WinWargus
												goal
****************************************************************************/
package planninglanguage.goals;

import java.util.LinkedList;
import java.util.List;

import org.jdom.Element;

import planninglanguage.conditions.AndCondition;
import planninglanguage.conditions.Condition;
import planninglanguage.conditions.NotCondition;
import planninglanguage.conditions.PlayerExistsCondition;
import planninglanguage.softconditions.AndSoftCondition;
import planninglanguage.softconditions.PlayerDefeatedSoftCondition;
import planninglanguage.softconditions.PlayerExistsSoftCondition;
import planninglanguage.softconditions.SoftCondition;
import util.XMLWriter;
import base.WargusGameState;

public class WinWargusGoal extends Goal implements Cloneable{
	
	LinkedList<Integer> m_opponentID;
	int m_playerID;
	
	public WinWargusGoal(int a_playerID, LinkedList<Integer> a_opponentID)
	{
		m_opponentID = a_opponentID;
		m_playerID = a_playerID;
	}
	
	public Object clone()
	{
		return new WinWargusGoal(m_playerID,m_opponentID);
	}
	
	public Condition generateSuccessCondition(WargusGameState a_gamestate)
	{ 
	    AndCondition ac = null;
	    Condition c = new PlayerExistsCondition(m_playerID) ;
	    int l_size = m_opponentID.size();
	    for(int i=0;i<l_size;i++)
	    {
	    	int l_opponentID = m_opponentID.get(i).intValue();
	    	NotCondition nc = new NotCondition(new PlayerExistsCondition(l_opponentID));
	    	if(ac==null)
	    		ac = new AndCondition(c,nc);
	    	else
	    		ac = new AndCondition(ac,nc);
	    }
	    if(ac==null)
	    	return c;
	    else
	    	return ac;
	}
	
	public SoftCondition generateSuccessSoftCondition(WargusGameState a_gamestate)
	{ 
	    AndSoftCondition ac = null;
	    SoftCondition c = new PlayerExistsSoftCondition(m_playerID) ;
	    int l_size = m_opponentID.size();
	    for(int i=0;i<l_size;i++)
	    {
	    	int l_opponentID = m_opponentID.get(i).intValue();
	    	SoftCondition nc = new PlayerDefeatedSoftCondition(m_playerID,l_opponentID,
	    			a_gamestate.getPlayerStrength(m_playerID),a_gamestate.getPlayerStrength(l_opponentID));		
	    	if(ac==null)
	    		ac = new AndSoftCondition(c,nc);
	    	else
	    		ac = new AndSoftCondition(ac,nc);
	    }
	    if(ac==null)
	    	return c;
	    else
	    	return ac;
	}	
	
	public float distance(Goal a_g) {
		if (!(a_g instanceof WinWargusGoal)) return 1;

		WinWargusGoal g = (WinWargusGoal)a_g;
		float d_p = 1;
		float d_op = 1;
		
		if (m_playerID == g.m_playerID) d_p = 0;
		if (m_opponentID.size() == g.m_opponentID.size()) d_op = 0;
		
		return d_p*0.25f + d_op*0.25f;	/* values are between 0 and 0.5 since at least the goal type is the same */ 
	}		
	
	public String toString() {
		return "WinWargusGoal( playerID = " + m_playerID + ")";
	}	
	
	public void writeXML(XMLWriter w) {
		w.tag(Goal.openTag + " " + Goal.XMLtype + "=\"" + 
				this.getClass().getSimpleName() + "\"");
		{
			w.tag(Goal.XMLplayerID, m_playerID);
			
			w.tag("opponents");
			{
				for (Integer i : m_opponentID) {
					w.tag("opponent", i.intValue());
				}
			}
			w.tag("/opponents");
		}
		w.tag(Goal.closeTag);
	}	
	protected static WinWargusGoal loadFromXML(Element e) {
		int playerID = Integer.parseInt(e.getChildText(XMLplayerID));
		LinkedList<Integer> l_opp = new LinkedList<Integer>();
		List opponents = e.getChild("opponents").getChildren("opponent");
		for (Object o : opponents) {
			Element oe = (Element) o;
			l_opp.add(Integer.parseInt(oe.getText()));
		}
		return new WinWargusGoal(playerID, l_opp);
	}
}

